/**
*	Class Name 	: WireClient.java
*	Description	: 
*	Modification Information
*	
*	     수정일		수정자				수정내용
*	----------	-----	-------------------------------
*	2011. 8. 8.	이주영	최초작성		
*
*	Copyright 2011 by (주)이타기술,  All right reserved.
*/

package gov.mogaha.ntis.cmm.mob.servlet;

import gov.mogaha.ntis.cmm.mob.servlet.bean.UserInfo;
import wire.client.HttpConnector;
import wire.client.RequestFailureException;
import wire.proto.Binding;
import android.content.Context;
import android.util.Log;

public class WireClient {
	
	// Single ton
	private static WireClient instance = null;
	public static void setInstance(WireClient instance) {
		WireClient.instance = instance;
	}
	private WireClient(){}
	public static WireClient getInstance(){
		if(getWireClient() == null){
			instance = new WireClient();
		}
		return instance;
	}
	
	private static WireClient getWireClient(){
		return instance;
	}
	//
	
	/** Wire server connector */
	private HttpConnector 	httpConnector 	= null;
	/** 사용자 정보(인증서) */
	private UserInfo 		userInfo 		= null;
	
	private String mWidl;
	private String mTag = "";
	
	/** 인증서 검증 */
	public static final int CERT_AUTH_ENTICATION_OK = 4000;	// 인증서 검증 완료
	public static final int USER_NULL_ERROR = 4001;			// 사용자 정보 없음
	public static final int SSOID_NULL_ERROR = 4002;		// SSO 정보 없음
	public static final int SSO_LOGIN_ERROR = 4003;			// SSO 로그인 실패 혹은 오류
	public static final int CONNECTION_TIME_OUT = 4004;		// 접속 시도시 타임 아웃
	public static final int ETC_ERROR = 4005;				// 알수 없는 올오류
	
	//개발테스트시에만 사용
	// 변경 Wire 서버설정 변경 - 김경환(11.09.20) -> 안승명차장 쪽지
	private final static String COMMON_WIDL = "mobile/RTP_GIS_COMMON";
	//private final String COMMON_SSO_WIDL = "mobile/RTP_COMMON";
	public boolean setConfig(String tag){
		if (!mTag.equalsIgnoreCase(tag) || httpConnector == null) {
			mTag = tag;
			return true;
		}
		return false;
	}
	/**
	 * Wire Server 연결 (최초 연결)
	 * @param ip	아이피
	 * @param port	포트
	 * @param tag	업무 태그
	 */
	public void connectWireServer(final String ip, final int port){
		try{
			if(httpConnector != null){
				httpConnector.quit();
				httpConnector = null;
			}
			httpConnector = new HttpConnector(ip, port);
			httpConnector.setEncoding("UTF8");
			httpConnector.setTag(mTag);
//			httpConnector.sslinit();
//			httpConnector.handshake(COMMON_WIDL);
		}
		catch (Exception e) {
			Log.e("", "", e);
		}
	}
	
	/**
	 * Wire Server 연결 (세션 유지시)
	 * @param ip	아이피
	 * @param port	포트
	 * @param tag	업무 태그
	 * @param sid	세션 ID
	 */
	public void connectWireServer(String ip, int port, String sid){
		Log.d("debug", "WireClient connectWireServer Start");
		try{
			if(httpConnector != null){
				httpConnector.quit();
				httpConnector = null;
			}
			httpConnector = new HttpConnector(ip, port);
			httpConnector.setEncoding("UTF8");
			httpConnector.setTag(mTag);
			httpConnector.setSID(sid);
			//httpConnector.sslinit(null);
			//httpConnector.handshake(mWidl);
		}
		catch (Exception e) {
			Log.d("debug", "WireClient connectWireServer Error");
			Log.e("", "", e);
		}
		Log.d("debug", "WireClient connectWireServer End");
	}
	
	/**
	 * wire 서버에 접속된 세션 ID를 반환
	 * @return SID
	 */
	public String getSID(){
		if(httpConnector == null){
			return null;
		}
		return httpConnector.getSID();
	}
	
	public boolean setSID(String sid){
		if(httpConnector == null){
			return false;
		}
		httpConnector.setSID(sid);
		return true;
	}
	
	public int getLastError(){
		return httpConnector.getLastError();
	}
	
	/**
	 * 인증서 겅증
	 * @param context
	 * @param binKey		인증서 바이너리
	 * @param pass			비밀번호
	 * @param phoneNumber	폰 번호
	 * @return
	 */
	public int certAuthentication(Context context, byte[] binKey, String pass, String phoneNumber) {
		int msg = -1;
		
		try{
			// 인증서 검증
			Binding voutputs = httpConnector.verifySign("mobile/RTP_GIS_COMMON", CertUtil.getSignData(context, pass, httpConnector.getSignMessage().getBytes()));			
			String user_cn = (String) voutputs.get("name");			
			
			// 사용자 ID 조회
			msg = setUserInfo(user_cn);
			if(msg > 0){
				return msg;
			}	
			
			// SSO 세션 생성
			msg = ssoLogin(user_cn, phoneNumber);
			if(msg > 0){
				return msg;
			}
			
			msg = CERT_AUTH_ENTICATION_OK;
		}
		catch (Exception e) {
			msg = ETC_ERROR;
		}
		return msg;
	}	
	
	/**
	 * 사용자의 정보를 저장
	 * @param user_cn	사용자 CN
	 * @return 결과 메세지
	 */
	private int setUserInfo(String user_cn){
		int msg = -1;		
		try{
			Binding inputs = new Binding();
			inputs.putEnc("user_cn", user_cn);
			Binding outputs = httpConnector.request("mobile/RTP_SMT_INTAPP", "selectUserID", inputs);
			
			String login_id = (String) outputs.get("login_id");
			String logon_id = (String) outputs.get("logon_id");
			
			if(login_id == null || login_id.equals("null")){				
				msg = USER_NULL_ERROR;
			}
			if(logon_id == null || logon_id.equals("null")){
				msg  = SSOID_NULL_ERROR;
			}			
			
			String dept_id = (String) outputs.get("dept_id");
			String dept_name = (String) outputs.get("dept_name");
			String sf_team_code = (String) outputs.get("sf_team_code");
			String sf_team_name = (String) outputs.get("sf_team_nm");
			String office_code = dept_id.substring(0, 3) + "0000";
			String gcc_code = office_code;
			
			userInfo = new UserInfo();
			userInfo.setUserCn(user_cn);
			userInfo.setLoginId(login_id);
			userInfo.setLogonId(logon_id);
			userInfo.setDeptId(dept_id);
			userInfo.setDeptName(dept_name);
			userInfo.setSfTeamCode(sf_team_code);
			userInfo.setSfTeamNm(sf_team_name);			
			userInfo.setOfficeCode(office_code);
			userInfo.setGccCode(gcc_code);
		}
		catch (Exception e) {
			Log.e("", "", e);
		}
		return msg;
	}
	
	/**
	 * 사용자 ID에 대한 SSO 세션을 생성
	 * @param user_cn 		사용자 CN
	 * @param phoneNumber	사용자 전화번호
	 * @return	결과 메세지
	 */
	private int ssoLogin(String user_cn, String phoneNumber){
		int msg = -1;
		try{
			Binding inputs = new Binding();
			inputs.putEnc("usercn", user_cn);
			inputs.putEnc("userid", userInfo.getLogonId());
			inputs.putEnc("userip", phoneNumber);		// 폰 번호
			Binding outputs = httpConnector.request("mobile/RTP_COMMON", "RTPSSOLogin", inputs);
			
			String ret = (String)outputs.get("value");
			if(!"success".equals(ret)) {
				msg = SSO_LOGIN_ERROR;
			}
		}
		catch (Exception e) {
			Log.e("", "", e);
		}
		return msg;
	}
	
	/**
	 * 검색 정보 반환
	 * @param widl	
	 * @param svc	서블릿명
	 * @param inputs 검색 양식
	 * @return Binding 
	 * @throws Exception
	 */
	public Binding getOutputs(String widl,String svc, Binding inputs) throws RequestFailureException{
		return httpConnector.request(widl, svc, inputs);
	}
	
	/**
	 * Wire Server 연결 종료
	 */
	public void destory(){
		try{
			if(httpConnector != null){
				httpConnector.quit();
			}
			httpConnector = null;
		}
		catch (Exception e) {
			Log.e("", "", e);
		}
	}
	
	/**
	 * 사용자 정보 저장
	 * @param userInfo 사용자 정보 객체
	 */
	public void setUserInfo(UserInfo userInfo){
		this.userInfo = userInfo;
	}
	
	/**
	 * 사용자 정보 반환
	 * @return UserInfo 사용자 정보
	 */
	public UserInfo getUserInfo(){
		return userInfo;
	}
}
